package cn.zhagzheguo.xk.util.excel;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 将传入的clazz进行反射并操作
 * 
 * @author zhagz
 * 
 */
public class Invoker {

	/**
	 * 传入的class对象
	 */
	private Class clazz;
	/**
	 * clazz反射获得的Object
	 */
	private Object obj;

	private Invoker() {
	}

	public Invoker(Class clazz) {
		this.clazz = clazz;
		obj = newInstance(clazz);

	}

	/**
	 * 反射出clazz对象的Object
	 * 
	 * @param clazz
	 */
	private Object newInstance(Class clazz) {
		try {
			return clazz.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			throw new RuntimeException("[Error]: Initiliaze class " + clazz.getName() + " failed.");
		}
	}

	/**
	 * 为每一个Object中的属性赋值
	 * 
	 * @param propertyName
	 *            属性名
	 * @param value
	 *            要赋的属性值
	 */
	public void setProperty(String propertyName, Object value) {
		String setMethodName = "";
		try {
			Field property = clazz.getDeclaredField(propertyName);
			setMethodName = "set" + property.getName().substring(0, 1).toUpperCase() + property.getName().substring(1);
			Method method = clazz.getMethod(setMethodName, property.getType());

			// System.out.println("propertyName=" + propertyName + ",value=" +
			// value + ",type=" + property.getType());
			if (property.getType() == java.lang.String.class) {
				method.invoke(obj, value.toString());
			} else if (property.getType() == java.lang.Integer.class || property.getType() == int.class) {
				if (value.toString().contains(".")) {
					value = value.toString().substring(0, value.toString().lastIndexOf("."));
				}
				method.invoke(obj, Integer.parseInt(value.toString()));
			} else if (property.getType() == java.lang.Short.class || property.getType() == short.class) {
				method.invoke(obj, Short.parseShort(value.toString()));
			} else if (property.getType() == java.lang.Float.class || property.getType() == float.class) {
				method.invoke(obj, Float.parseFloat(value.toString()));
			} else if (property.getType() == java.lang.Boolean.class || property.getType() == boolean.class) {
				method.invoke(obj, Boolean.parseBoolean(value.toString()));
			} else if (property.getType() == java.lang.Byte.class || property.getType() == byte.class) {
				method.invoke(obj, Byte.parseByte(value.toString()));
			} else if (property.getType() == java.lang.Character.class || property.getType() == char.class) {
				method.invoke(obj, value.toString().charAt(0));
			} else {
				method.invoke(obj, property.getType().cast(value));
				// throw new RuntimeException("[Error] Unrecognized format " +
				// property.getType().getClass() + ".");
			}

		} catch (NoSuchFieldException | SecurityException e) {
			throw new RuntimeException("[Error]: Cannot fonud property [" + propertyName + "] in class "
					+ clazz.getName() + ".");
		} catch (NoSuchMethodException e) {
			throw new RuntimeException("[Error]: Cannot fonud method " + setMethodName + "] in class "
					+ clazz.getName() + ".");
		} catch (IllegalAccessException | InvocationTargetException e) {
			throw new RuntimeException("[Error]: Type doesn't match in method " + setMethodName + "] in class "
					+ clazz.getName() + "with value [" + value + "].");
		}
	}

	/**
	 * 返还已经赋值完毕后的Object
	 * 
	 * @return
	 */
	public Object returnObject() {
		return obj;
	}

}
